#include <iostream>
#include <cstdlib>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdio>
#include <sstream>
#include <deque>

using namespace std;

typedef long long int64;
typedef unsigned int ui;

set<int64> hash;
set<int> enable;

int n, m;

int mark[100];
int invalid[100];
int wall[10][10];

#define twoL(x) (int64(1) << int64(x))
#define two(x) (1 << (x))

//#define incmark(w) ++mark[(w)]; if (mark[(w)] == 1) enable.insert((w));
//#define decmark(w) --mark[(w)]; if (mark[(w)] == 0) enable.erase((w));

void incmark(int w)
{
    ++mark[(w)]; if (mark[(w)] == 1) enable.insert((w));
}

void decmark(int w)
{
    --mark[(w)]; if (mark[(w)] == 0) enable.erase((w));
}

void add(int k)
{
	if (invalid[k])
	    abort();
	invalid[n * n - k - 1] = true;
	invalid[k] = true;
	enable.erase(k);
	int x = k / n;
	int y = k - x * n;
	if (x > 0)
		incmark(k - n);
	if (x < n - 1)
		incmark(k + n);
	if (y > 0)
		incmark(k - 1);
	if (y < n - 1)
		incmark(k + 1);
}

void remove(int k)
{
	if (!invalid[k])
	    abort();
	invalid[n * n - k - 1] = false;
	invalid[k] = false;
	enable.insert(k);
	int x = k / n;
	int y = k - x * n;
	if (x > 0)
		decmark(k - n);
	if (x < n - 1)
		decmark(k + n);
	if (y > 0)
		decmark(k - 1);
	if (y < n - 1)
		decmark(k + 1);
}

int validCount = 0;

#if 0
struct line
{
	int pre[8];
};

bool operator<(const line &a, const line &b)
{
	for (int i = 0; i < n; ++i)
	{
		if (a.pre[i] < b.pre[i]) return true;
		if (a.pre[i] > b.pre[i]) return false;
	}
	return false;
}
#else
typedef int line[16];
#endif

void DFS(int64 s, int cnt)
{
	if (hash.find(s) != hash.end())
		return;
	hash.insert(s);
	if (cnt == n * n / 2)
	{
		++validCount;
		if (validCount % 10000 == 0)
			cout << validCount << endl;
#if 0
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < n; ++j)
			    cout << ((s >> (i * n + j)) & 1);
			cout << endl;
		}
		cout << endl;
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < n; ++j)
			    cout << (invalid[i * n + j] ? 'x' : 'o');
			cout << endl;
		}
		cout << endl;
#endif
		return;
	}
	vector<int> x;
	for (set<int>::iterator it = enable.begin(); it != enable.end(); ++it)
	{
		if (!invalid[*it])
			x.push_back(*it);
	}
		
	for (int i = 0; i < x.size(); ++i)
	{
		add(x[i]);
		int64 t = s | (int64)twoL(x[i]);
		DFS(t, cnt + 1);
		remove(x[i]);
	}
}

inline int find(int *a, int i)
{
	int j, k;
	for (j = i; a[j] != j; j = a[j]);
	while (a[i] != j)
	{
		k = a[i];
		a[i] = j;
		i = k;
	}
	return j;
}

inline void merge(int *a, int i, int j)
{
	i = find(a, i);
	j = find(a, j);
	a[i] = j;
}

inline void bits_to_line(int s, line &a)
{
	a[0] = 0;
	for (int i = 1; i < n; ++i)
		if (((s >> i) & 1) ^ ((s >> (i - 1) & 1)))
			a[i] = i;
		else
		    a[i] = a[i - 1];
}

inline int line_to_bits(line &a)
{
	int s = 0;
	int now = 0;
	for (int i = 1; i < n; ++i)
	{
	    if (find(a, i) != find(a, i - 1))
			now = 1 - now;
		if (now)
		    s += two(i);
	}
	return s;
}

inline void value_to_line(int s, line &a)
{
	for (int i = 0; i < n; ++i)
	{
		a[i] = s % (i + 1);
		s /= (i + 1);
	}
}

inline int line_to_value(line &a)
{
	static int pre[8], digit[8];
	memset(pre, 255, sizeof(pre));
	for (int i = 0; i < n; ++i)
	{
		int x = find(a, i);
		if (pre[x] < 0)
			digit[i] = i;
		else
			digit[i] = pre[x];
		pre[x] = i;
	}
	
	int s = 0;
	for (int i = n - 1; i >= 0; --i)
	    s = s * (i + 1) + digit[i];
	return s;
}

bool do_merge(line &a, line &b, line &c, int common)
{
	for (int i = 0; i < n; ++i) c[i] = b[i], c[i + n] = a[i] + n;

	for (int i = 0; i < n; ++i) if (two(i) & common)
		merge(c, i, i + n);

	for (int i = 0; i < n; ++i)
	{
		c[i] = find(c, i);
		if (c[i] >= n)
		{
			c[c[i]] = i;
			c[i] = i;
		}
	}
	for (int i = 0; i < n; ++i)
		if (find(c, i + n) >= n)
		    return false;

	return true;
}

bool fmerge(line &a, line &b, line &c)
{
	int s = line_to_bits(a);
	int t = line_to_bits(b);
	int common = (s & t) | (~s & ~t);
	
	return do_merge(a, b, c, common);
}

bool bmerge(line &a, line &b, line &c)
{
	int s = line_to_bits(a);
	int t = line_to_bits(b);
	int common = (s & ~t) | (~s & t);

	return do_merge(a, b, c, common);
}

void print(line &a)
{
	for (int i = 0; i < n; ++i) printf("%d ", a[i]);
	printf("\n");
}

bool checkit(line &c, int *block)
{
	if (block[0] && find(c, 0) == find(c, n)) return false;
	if (block[n] && find(c, n - 1) == find(c, n + n - 1)) return false;
	for (int i = 0; i < n - 1; ++i) if (block[i + 1])
	{
		int x = find(c, i);
		if (find(c, i + 1) != x) continue;
		if (find(c, n + i) != x) continue;
		if (find(c, n + i + 1) != x) continue;
		return false;
	}
	return true;
}

void process()
{
	n = m * 2;
	line a, b, c;
	
	map<int, ui> count;
	
	for (int s = 0; s < two(n); s += 2)
	{
		bits_to_line(s, a);
//		printf("%d: ", s);
//		print(a);
		bool check = true;
		for (int i = 0; check && i < n - 1; ++i)
		    if (a[i] == a[i + 1] && wall[0][i + 1])
		        check = false;
		if (check)
			count[line_to_value(a)] = 1;
	}

	for (int i = 0; i < m - 1; ++i)
	{
//		printf("line %d, counter.size() = %d:\n", i, count.size());
        map<int, ui> nc;
        for (map<int, ui>::iterator it = count.begin(); it != count.end(); ++it)
        {
			value_to_line(it->first, a);
//			cout << it->second << ' ';
//			print(a);
			for (int t = 0; t < two(n); t += 2)
			{
				bits_to_line(t, b);
				
				if (fmerge(a, b, c) && checkit(c, wall[i + 1]))
				{
//					puts("fmerge");
//					print(a);
//					print(b);
//					print(c);
					nc[line_to_value(c)] += it->second;
				}
					
				if (bmerge(a, b, c) && checkit(c, wall[i + 1]))
					nc[line_to_value(c)] += it->second;
			}
		}
		count = nc;
//		return;
	}
	
	ui answer = 0;
	
//	puts("caculation");
	
    for (map<int, ui>::iterator it = count.begin(); it != count.end(); ++it)
    {
		value_to_line(it->first, a);
		for (int i = 0; i < n; ++i)
			b[i] = n - a[n - i - 1] - 1;
			
		int x = line_to_bits(a);
		int y = line_to_bits(b);
		int common;
		if ((x & two(0)) ^ (y & two(n - 1)))
		    common = (x ^ ~y) | (~x ^ y);
		else
		    common = (x ^ y) | (~x ^ ~y);
		    
		do_merge(a, b, c, common);
		
		if (!checkit(c, wall[n / 2]))
		    continue;

		set<int> temp;
		for (int i = 0; i < 2 * n; ++i)
		    temp.insert(c[i]);
#if 0
		printf("it->second = %d, common = %d, ", it->second, common);
		for (int i = 0; i < 2 * n; ++i)
		    printf("%d ", c[i]); printf("\n");
		for (int i = 0; i < n; ++i)
		    printf("%d ", wall[n / 2][i]); printf("\n");
		print(a);
#endif
		if (temp.size() != 2)
		    continue;
		answer += it->second;
	}
	cout << answer * 2 << endl;
}

int main()
{
#if 0
	n = 6;
	hash.clear();
	enable.clear();
	enable.insert(0);
	
	memset(mark, 0, sizeof(mark));
	memset(invalid, 0, sizeof(invalid));
	mark[0] = 1;
	
	add(0);
	DFS(twoL(0), 1);
	cout << validCount << endl;
#else
	int p;
	cin >> m >> p;
	n = m * 2;
	
	memset(wall, 0, sizeof(wall));
	
	for (int i = 0; i < p; ++i)
	{
		int x, y;
	    cin >> x >> y;
	    if (x <= m)
		    wall[x][y] = 1;
	    if (x >= m)
	        wall[n - x][n - y] = 1;
	}
	process();
#endif
//	getc(stdin);
//	getc(stdin);
	return 0;
}
